<template>
    <UxDialog :visible="!!dialog_overlapping" @close="dialog_overlapping && dialog_overlapping(false)">
        <div class="dialog-overlapping">
            <h3>Unable to save</h3>
            <p>When placing images in different print areas, please leave a minimum distance of 2 inches between the images to ensure that they are printed correctly and without any overlap.</p>
            <figure>
                <img src="https://img.podpartner.com/static/images-20230328/designer-overlapping.png" />
            </figure>
            <button @click="dialog_overlapping(true)" type="primary">Confirm</button>
        </div>
    </UxDialog>
</template>
<script>
import { mapGetters, mapState } from "vuex";
import DesignEditor from '@/utils/DesignEditor.js';
import { fabric as Fabric } from "fabric";

export default {
    data () {
        return {
            dialog_overlapping: null,
        };
    },
    computed: {
        ...mapGetters("designer", {
            pieces: "getPieces",
        }),
    },
    methods: {
        // 检查重叠
        check () {
            // 基于线框图，且只看正面和背面
            const pieces = this.pieces.filter(i => i.type != 2);
            const scale = 0.25;
            const front = [];
            const back = [];
            const promises = [];

            // 检查设计区重叠
            const checkPieces = (pieces) => {

                return Promise.all(pieces.map(piece => {

                    const option = {
                        canvas_model: "simple",
                        canvas_scale: scale,
                        canvas_width: piece.canvas_width,
                        canvas_height: piece.canvas_height,
                        design_layers: piece.layers,
                    };

                    return new DesignEditor(Fabric, null, option).renderLayers().then(fabric => {

                        const design = fabric.lowerCanvasEl;
                        const canvas = document.createElement('canvas');
                        const ctx = canvas.getContext("2d");

                        // 保存位置
                        const saveX = piece.canvas_left * scale;
                        const saveY = piece.canvas_top * scale;
                        const saveW = piece.canvas_width * scale;
                        const saveH = piece.canvas_height * scale;

                        canvas.width = piece.outer_width * scale;
                        canvas.height = piece.outer_height * scale;

                        ctx.save();
                        ctx.translate(saveX + 0.5 * saveW, saveY + 0.5 * saveH);
                        ctx.rotate(piece.canvas_rotate * Math.PI / 180);
                        ctx.drawImage(design, 0, 0, design.width, design.height, -0.5 * saveW, -0.5 * saveH, saveW, saveH);
                        ctx.translate(-saveX - 0.5 * saveW, -saveY - 0.5 * saveH);
                        ctx.restore();


                        // 扩散处理
                        // pixel 表示一个一维数组，包含以 RGBA 顺序的数据，数据使用 0 至 255（包含）的整数表示。
                        // 一个像素点占4个位置
                        // 加粗宽度是真实大小300px
                        const radius = Math.round(piece.canvas_zoom * 300 * scale);
                        const width = parseInt(canvas.width);
                        const height = parseInt(canvas.height);
                        const matrix = new Array(width).fill(0).map(i => new Array(height).fill(0));
                        const pixel = ctx.getImageData(0, 0, width, height).data || [];

                        matrix.map((arr, x) => {
                            arr.map((val, y) => {
                                const point = y * width + x;
                                const alpha = pixel[point * 4 + 3];

                                if (alpha != 0) {
                                    const x1 = Math.max(x - radius, 0)
                                    const x2 = Math.min(x + radius, width - 1);
                                    const y1 = Math.max(y - radius, 0)
                                    const y2 = Math.min(y + radius, height - 1);

                                    for (let xn = x1; xn <= x2; xn++) {
                                        for (let yn = y1; yn <= y2; yn++) {
                                            if (matrix[xn][yn] != 0) {
                                                // 已经显示，不用再计算
                                            } else if (Math.sqrt(Math.pow(x - xn, 2) + Math.pow(y - yn, 2)) < radius) {
                                                matrix[xn][yn] = 1;
                                            }
                                        }
                                    }
                                }
                            })
                        })

                        return Promise.resolve({
                            surface_name: piece.surface_name,
                            canvas_name: piece.canvas_name,
                            canvas: canvas,
                            matrix: matrix,
                        })
                    })
                })).then(result => {

                    const width = Math.max(...result.map(i => i.canvas.width));
                    const height = Math.max(...result.map(i => i.canvas.height));
                    const overlap = {
                        size: width * height,
                        index: 0,
                        cover: [],
                    }

                    while (overlap.index < overlap.size) {
                        const x = overlap.index % width;
                        const y = parseInt(overlap.index / width)
                        const cover = result.filter(item => item.matrix[x][y] != 0)
                        if (cover.length > 1) {
                            overlap.index += 1;
                            overlap.cover = cover;
                            break;
                        } else {
                            overlap.index += 1;
                        }
                    }

                    if (overlap.cover.length > 0) {
                        return Promise.reject(overlap);
                    } else {
                        return Promise.resolve('ok');
                    }

                })
            }

            pieces.map(piece => {
                if (piece.layers.length == 0) {
                    // 没有图层不管
                } else if (piece.surface_name == 'Front Side') {
                    front.push(piece);
                } else if (piece.surface_name == 'Back Side') {
                    back.push(piece);
                }
            })

            front.length > 1 && promises.push(checkPieces(front));
            back.length > 1 && promises.push(checkPieces(back));

            return Promise.all(promises).then(result => {
                return Promise.resolve(result)
            }).catch(e => {
                return new Promise((resolve, reject) => {
                    this.dialog_overlapping = () => {
                        this.dialog_overlapping = null;
                        reject('piece overlapping');
                    }
                })
            })
        },


    },
};
</script>
<style lang="scss" scoped>
.dialog-overlapping {
    width: 360px;
    padding: 24px 14px 14px;
    box-sizing: border-box;
    margin: 0 auto;

    & > h3 {
        font-size: 16px;
        font-family: Roboto-Medium, Roboto;
        font-weight: 500;
        color: #000000;
        line-height: 18px;
        text-align: center;
    }

    p {
        margin-top: 16px;
        font-size: 14px;
        font-family: Roboto-Regular, Roboto;
        font-weight: 400;
        color: #000000;
        line-height: 20px;
    }

    figure {
        display: block;
        position: relative;
        margin-top: 16px;
        padding-bottom: 76.82%;
        img {
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
        }
    }

    button {
        width: 100%;
        margin-top: 16px;
        height: 38px;
    }
}
</style>
